package org.ethan.order.service.impl;

import org.apache.commons.lang3.time.DateUtils;
import org.ethan.basic.exception.BasicException;
import org.ethan.basic.service.impl.BaseServiceImpl;
import org.ethan.basic.util.LoginContext;
import org.ethan.order.domain.OrderAddress;
import org.ethan.order.domain.OrderPet;
import org.ethan.order.domain.OrderPetDetail;
import org.ethan.order.dto.OrderDto;
import org.ethan.order.service.IOrderAddressService;
import org.ethan.order.service.IOrderPetDetailService;
import org.ethan.order.service.IOrderPetService;
import org.ethan.pay.domain.PayBill;
import org.ethan.pay.service.IPayBillService;
import org.ethan.pet.domain.Pet;
import org.ethan.pet.service.IPetService;
import org.ethan.user.domain.LoginInfo;
import org.ethan.user.domain.UserAddress;
import org.ethan.user.mapper.UserAddressMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

/**
 * 下单业务实现
 */
@Service
@Transactional
public class OrderPetServiceImpl extends BaseServiceImpl<OrderPet> implements IOrderPetService {

    @Autowired
    private IPetService petService;

    @Autowired
    private IOrderPetDetailService orderPetDetailService;

    @Autowired
    private UserAddressMapper userAddressMapper ;

    @Autowired
    private IOrderAddressService orderAddressService;

    @Autowired
    private IPayBillService payBillService;
    /**
     * 下单
     * 1.校验参数,
     * 2.查询宠物信息，判断宠物上架
     * 3.查询用户地址，支付方式
     * 4.创建订单号 ，计算支付超时时间，保存订单数据
     * 5.保存订单明细
     * 6.保存订单地址
     * 7.宠物表，库存-1,下单就减库存
     * @param dto ：下单参数
     */
    @Override
    public String submitOrder(OrderDto dto) {

        // 参数校验
        // 1.校验参数
        Long addressId = dto.getAddressId();
        Integer payType = dto.getPayType();
        Long petId = dto.getPetId();
        if(null == addressId){
            throw new BasicException("非法地址");
        }
        if(null == payType){
            throw new BasicException("非法支付类型");
        }
        if(null == petId){
            throw new BasicException("非法宠物ID");
        }
        // 宠物&地址查询
        // 2.查询宠物信息，判断宠物上架
        // 宠物类型，宠物店铺关联查询
        Pet pet = null;
        synchronized (this){
            pet =  petService.findOnsalePetById(petId);
            if(null == pet){
                throw new BasicException("非法宠物");
            }

            if(pet.getStorage_num() == null || pet.getStorage_num().intValue() == 0){
                throw new BasicException("无货！！！");
            }
            pet.setStorage_num(pet.getStorage_num() - 1);
            petService.update(pet);
        }


        // 3.查询用户地址，支付方式
        UserAddress userAddress = userAddressMapper.selectById(addressId);
        if(null == userAddress){
            throw new BasicException("非法地址");
        }

        // 4.创建订单号
        String orderNo = UUID.randomUUID().toString().replaceAll("-","" );
        Date now = new Date();
        // 计算支付超时时间，保存订单数据
        Date payExpireTime = DateUtils.addMinutes(now, 30);
        // 保存订单
        OrderPet orderPet = new OrderPet();
        // 摘要
        orderPet.setDigest("购买："+pet.getName()+"下单");
        orderPet.setCreateTime(now);
        // 支付超时时间
        orderPet.setPayExpireTime(payExpireTime);
        // 订单号
        orderPet.setOrderSn(orderNo);
        orderPet.setPayType(payType);
        // 状态:待支付
        orderPet.setState(OrderPet.STATE_WAIT_PAY);
        orderPet.setTotalCount(1);
        // 金额+邮费
        orderPet.setTotalPrice(pet.getSaleprice().add(new BigDecimal("15")));
        //获取登录用户
        LoginInfo loginContext = LoginContext.getLogin();
        // 判断是否登录（防御性编程）
        if(loginContext == null){
            throw new BasicException("请登录");
        }
        orderPet.setUserId(loginContext.getId());

        // 保存订单（super可不要）
        super.add(orderPet);
        // 保存订单明细
        // 5.保存订单明细
        OrderPetDetail detail = new OrderPetDetail();
        detail.setCount(1);
        detail.setCreatetime(now);
        // 宠物名
        detail.setName(pet.getName());
        // 订单
        detail.setOrderId(orderPet.getId());
        detail.setOrderSn(orderNo);
        detail.setPetId(pet.getId());
        // 价格
        detail.setPrice(pet.getSaleprice());
        // 图片
        detail.setResources(pet.getResources());
        // 店铺
        detail.setShopId(pet.getShop().getId());
        detail.setShopName(pet.getShop().getName());
        // 保存详情
        orderPetDetailService.add(detail);

        // 6.保存订单地址
        OrderAddress orderAddress = new OrderAddress();
        // 属性拷贝
        BeanUtils.copyProperties(userAddress, orderAddress);
        orderAddress.setOrderId(orderPet.getId());
        orderAddress.setOrderSn(orderNo);
        orderAddress.setCreateTime(now);
        // 保存地址
        orderAddressService.add(orderAddress);

        // 7.宠物表，在下单时就减库存 -1

        /*
                防止超卖，上锁（线程同步）

                存在问题：pet是局部变量，在各自线程中都有值，
                当一个减了1之后，另一个还可以减1, （代码移动到上面）
         */
        /*synchronized (this){
            if(pet.getStorage_num() == null || pet.getStorage_num().intValue() == 0){
                throw new BasicException("无货！！！");
            }
            pet.setStorage_num(pet.getStorage_num() - 1);
        }
        petService.update(pet);*/

        // 保存支付单
        payBillService.save(
                orderPet.getId(),   // 外键
                PayBill.BUSINESS_TYPE_PET, //业务类型
                "购买："+pet.getName()+"，支付："+orderPet.getTotalPrice(),
                orderPet.getTotalPrice(), //总价格
                dto.getPayType(),//支付方式用户选的
                pet.getShop().getId() ,//店铺
                pet.getShop().getName(),
                orderPet.getOrderSn()); //单号

        // 返回订单号
        return orderNo;


    }
}

